package com.boarsoft.flow.trace;

import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

import org.slf4j.MDC;

import com.boarsoft.flow.core.FlowConfig;

/**
 * 一个流程有一个主的FlowTrace<br>
 * 每个FlowTrace有一个堆栈和一个执行记录列表<br>
 * 
 * @author Mac_J
 *
 */
public class SimpleFlowTrace implements FlowTrace, Serializable {
	private static final long serialVersionUID = -2626547132149047535L;

	/** */
	protected String flowId; //
	/** */
	protected String id; //
	/** */
	protected long startTime; //
	/** */
	protected long endTime; //
	/** 顺序执行的记录列表 */
	protected List<SimpleFlowStep> steps = new LinkedList<SimpleFlowStep>();
	/** */
	protected String threadName; //
	/** */
	protected short status; //
	/** 此流程调用链的上级RPC调用链的ID，但不是同进程的父流程的ID（这种会合并） */
	protected String parent;

	/** 执行堆栈：流程在进入try/tx等节点时，会递归执行go方法，因而产生堆栈 */
	protected transient Stack<SimpleFlowStep> stack = new Stack<SimpleFlowStep>();

	public SimpleFlowTrace() {
		parent = MDC.get(FlowConfig.TRACE_TAG);
		this.threadName = Thread.currentThread().getName();
		this.startTime = new Date().getTime();
	}

	public SimpleFlowTrace(String flowId) {
		this();
		this.flowId = flowId;
	}

	public SimpleFlowTrace(String flowId, String id) {
		this(flowId);
		this.id = id;
	}

	@Override
	public void merge(FlowTrace trace) {
		SimpleFlowStep step = stack.peek();
		step.getTraces().add(trace);
	}

	@Override
	public void push(String step, Object input) {
		stack.push(new SimpleFlowStep(step, input));
	}

	@Override
	public void pop(Object output) {
		SimpleFlowStep step = stack.pop();
		step.end(output);
		steps.add(step);
	}

	@Override
	public SimpleFlowStep peek() {
		return stack.peek();
	}

	@Override
	public void add(SimpleFlowStep step) {
		steps.add(step);
	}

	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public void setFlowId(String flowId) {
		this.flowId = flowId;
	}

	@Override
	public String getId() {
		return id;
	}

	@Override
	public List<SimpleFlowStep> getSteps() {
		return steps;
	}

	@Override
	public void setSteps(List<SimpleFlowStep> steps) {
		this.steps = steps;
	}

	@Override
	public String getFlowId() {
		return flowId;
	}

	@Override
	public String getThreadName() {
		return threadName;
	}

	@Override
	public void setThreadName(String threadName) {
		this.threadName = threadName;
	}

	@Override
	public long getStartTime() {
		return startTime;
	}

	@Override
	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}

	@Override
	public long getEndTime() {
		return endTime;
	}

	@Override
	public void setEndTime(long endTime) {
		this.endTime = endTime;
	}

	@Override
	public short getStatus() {
		return status;
	}

	@Override
	public void setStatus(short status) {
		this.status = status;
	}

	@Override
	public String getParent() {
		return parent;
	}

	@Override
	public void setParent(String parent) {
		this.parent = parent;
	}

}
